#include <torch/torch.h>
#include <iostream>

int main() {
	// Create tensor x and initialize it to 2
	torch::Tensor x = torch::tensor({2.0}, torch::kFloat64);
	x.requires_grad_(true);   // Enable automatic differentiation

	// Create tensor y and initialize it to 5
	torch::Tensor y = torch::tensor({5.0}, torch::kFloat64);
	y.requires_grad_(true);   // Enable automatic differentiation

	// Compute z = ln(x) + y^2
	torch::Tensor z = torch::log(x) + torch::pow(y, 2);

	// Output the value of z
	// std::cout << "z = " << z.item<float>()  << std::endl;

	// Backward pass to compute gradients
	z.backward();

	// Get the gradient of z with respect to x
	float dz_dx = x.grad().item<float>();

	// Get the gradient of z with respect to y
	float dz_dy = y.grad().item<float>();

	// Output the results 
	std::cout << "Partial derivative of z with respect to x at (2,5): " << dz_dx << std::endl;
	std::cout << "Partial derivative of z with respect to y at (2,5): " << dz_dy << std::endl;

	return 0;
}
